package com.whately.core.base.model;

import com.alibaba.fastjson.annotation.JSONField;
import com.whately.core.base.exception.ErrorCode;
import com.whately.core.base.utils.GsonUtils;
import com.whately.core.base.utils.MD5Util;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;

/**
 * API 响应格式
 * 正常code 为 200
 * 错误为 400 或者其它400以上
 */
@ApiModel(value = "响应结果")
@ToString
public class ApiResponse<T> {

    private static String SUCCESS_DEFAULT_MSG = "操作成功";
    private static int SUCCESS_DEFAULT_CODE = 200;

    public static final ApiResponse SUCCESS = new ApiResponse();
    public static final ApiResponse FAILURE = new ApiResponse(400,"操作失败",null);

    @Getter
    @ApiModelProperty(value = "状态码")
    private int code;

    @Getter
    @ApiModelProperty(value = "描述信息")
    private String message;

    @Getter
    @ApiModelProperty(value = "md5校验值")
    private String md5;

    @Getter
    @ApiModelProperty(value = "业务调用返回数据体")
    private T data;

    //不序列化该字段，记录日志用
    @Getter
    @Setter
    @JSONField(serialize = false)
    @ApiModelProperty(hidden = true)
    private Object recorderInfo;

    @Getter
    @Setter
    @JSONField(serialize = false)
    @ApiModelProperty(hidden = true)
    private boolean recorderIgnore;

    /**
     * 默认构造
     */
    private ApiResponse() {
        this(SUCCESS_DEFAULT_CODE, SUCCESS_DEFAULT_MSG, null);
    }


    private ApiResponse(int code, String message, T data) {
        this.code = code;
        if (StringUtils.isNotEmpty(message)) {
            this.message = message;
        }
        this.data = data;
    }

    public static boolean  isCorrectResponse(ApiResponse response){
        if(response!=null&&response.getCode()==SUCCESS_DEFAULT_CODE){
            return true;
        }
        return  false;
    }

    public static boolean  isCorrectResponseAndNotNullReturnData(ApiResponse response){
        if(response!=null&&response.getCode()==SUCCESS_DEFAULT_CODE&&response.getData()!=null){
            return true;
        }
        return  false;
    }

    /**

     public String toString() {
     return ReflectionToStringBuilder.toString(this);
     }

     */
    /**********************************************
     * builder
     **********************************************/
    public static <T> ApiResponseBuilder<T> builder() {
        return new ApiResponseBuilder<>();
    }

    /**
     * 构造响应。 使用方式：
     * <p/>
     * <pre>
     *  ApiResponse<FileSenderBO> apiResponse = ApiResponse.<FileSenderBO>builder().code(200).message("zxxx").data(bb).build();
     *
     *  ApiResponse<FileSenderBO> apiResponse2 = new ApiResponse.ApiResponseBuilder<FileSenderBO>().code(200).message("zxxx").data(bb).build();
     * </pre>
     */
    public static class ApiResponseBuilder<T> {
        ApiResponse<T> apiResponse = new ApiResponse();;

        ApiResponseBuilder() {
        }

        /**
         * 设置错误码。默认200
         *
         * @param code 错误码
         * @return ApiResponseBuilder
         */
        public ApiResponseBuilder<T> code(int code) {
            apiResponse.code = code;
            return this;
        }

        /**
         * 设置消息。默认[操作成功]
         *
         * @param message 错误消息
         * @return ApiResponseBuilder
         */
        public ApiResponseBuilder<T> message(String message) {
            apiResponse.message = message;
            return this;
        }

        /**
         * 从Errorcode中设置错误码和错误消息
         *
         * @param errorCode
         * @return
         */
        public ApiResponseBuilder<T> code(ErrorCode errorCode) {
            apiResponse.code = errorCode.getCode();
            apiResponse.message = errorCode.getMessage();
            return this;
        }

        /**
         * 设置响应的具体内容
         *
         * @param data 响应的具体内容
         * @return 内容
         */
        public ApiResponseBuilder<T> data(T data) {
            apiResponse.data = data;
            return this;
        }

        public ApiResponseBuilder<T> recorderInfo(Object recorder) {
            apiResponse.recorderInfo = recorder;
            return this;
        }

        public ApiResponseBuilder<T> recorderIgnore(boolean ignore) {
            apiResponse.recorderIgnore = ignore;
            return this;
        }

        public ApiResponse<T> build() {
            //参数校验, 并且设置默认值
            if(this.apiResponse.code ==SUCCESS_DEFAULT_CODE){
                if (StringUtils.isEmpty(apiResponse.message)) {
                    this.apiResponse.message = SUCCESS_DEFAULT_MSG;
                }
            }else{
                if (StringUtils.isEmpty(apiResponse.message)||SUCCESS_DEFAULT_MSG.equals(apiResponse.message)) {
                    this.apiResponse.message = "操作失败";
                }
            }

            //构造JSON
            apiResponse.md5 = getMd5();
            return apiResponse;
        }

        //计算MD5
        private String getMd5() {
            /*if (this.apiResponse.data == null) {
                this.apiResponse.data = new ArrayList<>(0);
            }*/
            String json = GsonUtils.toJsonString(this.apiResponse.data == null ? new ArrayList<>(0) : this.apiResponse.data);
            return MD5Util.md5(json);
        }

    }

}
